#include "H264PPS.hpp"
#include "Bistream.hpp"
#include <assert.h>




int NaluPPS::Parse(NaluSPS (&msps)[H264_MAX_SPS_COUNT]){
    uint8_t* buf = rbsp.RBSPBuf;
    int buflen = rbsp.RBSPLen;

    BitStream bitstream(buf+1,bufLen-1);
    
    pic_parameter_set_id = bitstream.ReadUE();
    seq_parameter_set_id = bitstream.ReadUE();
    NaluSPS sps = msps[seq_parameter_set_id];
    entropy_coding_mode_flag = bitstream.ReadU1();
    bottom_field_pic_order_in_frame_present_flag = bitstream.ReadU1();
    
    num_slice_groups_minus1 = bitstream.ReadUE();
    if(num_slice_groups_minus1 > 0){
        slice_group_map_type = bitstream.ReadUE();
        if( slice_group_map_type == 0){
            for(int i = 0; i < num_slice_groups_minus1; i++){
                run_length_minus1[i] = bitstream.ReadUE();
            }
        }
        else if(slice_group_map_type == 2){
            for(int i = 0; i < num_slice_groups_minus1; i++){
                top_left[i] = bitstream.ReadUE();
                bottom_right[i] = bitstream.ReadUE();
            }
        }
        else if(slice_group_map_type == 3 || slice_group_map_type ==4 || slice_group_map_type == 5){
            slice_group_change_direction_flag = bitstream.ReadU1();
            slice_group_change_rate_minus1 = bitstream.ReadUE();
        }
        else if(slice_group_map_type == 6){
            pic_size_in_map_units_minus1 = bitstream.ReadUE();
            int v = h264_log2(num_slice_groups_minus1+1);
            for(int i = 0; i <= pic_size_in_map_units_minus1; i++){
                slice_group_id[i] = bitstream.ReadU(v);
            }
        }

    }
    SliceGroupChangeRate = slice_group_change_rate_minus1 + 1;
    PicSizeInMapUnits = pic_size_in_map_units_minus1 + 1;
    
    num_ref_idx_l0_default_active_minus1 = bitstream.ReadUE();
    num_ref_idx_l1_default_active_minus1 = bitstream.ReadUE();
    weighted_pred_flag = bitstream.ReadU1();
    weighted_bipred_idc = bitstream.ReadU(2);
    pic_init_qp_minus26 = bitstream.ReadSE();
    pic_init_qs_minus26 = bitstream.ReadSE();
    chroma_qp_index_offset = bitstream.ReadSE();
    deblocking_filter_control_present_flag = bitstream.ReadU1();
    constrained_intra_pred_flag = bitstream.ReadU1();
    redundant_pic_cnt_present_flag = bitstream.ReadU1();
    if(!bitstream.isFull()){
        transform_8x8_mode_flag = bitstream.ReadU1();
        pic_scaling_matrix_present_flag = bitstream.ReadU1();
        if(pic_scaling_matrix_present_flag){
            for(int i = 0; i < 6 + ((sps.chroma_format_idc != 3) ? 2: 6)*transform_8x8_mode_flag; i++){
                pic_scaling_list_present_flag[i] = bitstream.ReadU1();
                if(pic_scaling_list_present_flag[i]){
                    if(i < 6){
                        scaling_list(ScalingList4x4[i],16, UseDefaultScalingMatrix4x4Flag[i], bitstream);
                    }
                    else{
                        scaling_list(ScalingList8x8[i-6], 64, UseDefaultScalingMatrix8x8Flag[i-6]);
                    }
                }

            }
            second_chroma_qp_index_offset = bitstream.ReadSE();
        }

        bitstream.ReadtoEnd();
    }
    

    return 0;
}